// id userId adminId userType(user/admin ) content read(布尔) goodsId
// groupId userId adminId
// websocket 发送消息格式 { type(消息类型：caht聊天信息，status，对方在线状态(online,offline))，id:对方用户id，content: 内容(status时为true/false) }
// 发送空消息 验证在线状态
// 用来存储建立了的链接，（真实项目中请使用数据库代替）
const model = require("../models")
const User = model.user.User //获取模型
const ShopUser = model.shopUser.ShopUser //获取模型
const ChatList = model.chat_list.ChatList //获取模型
const ChatGroup = model.chat_group.ChatGroup
const { getFile } = require('../models/getfile')

const wsObj = {} // 临时缓存（是否在线）

exports.websocket = async(ctx) => {
  const { id, userType } = ctx.query
  const wsKey = `${userType}${id}`
  console.log(id, userType)

  wsObj[wsKey] = ctx // 把连接存在缓存(在线状态)
  wsObj[wsKey].websocket.send(sendData('system', { id, userType, status: 'online', content: '连接成功'}))

  for (const prop in wsObj) { // 给其他人发送上线通知(在线状态)
    if (wsKey !== prop) {
      wsObj[prop].websocket.send(sendData('system', { id, userType, status: 'online', content: `${prop}用户上线了`}))
    }
  }
  ctx.websocket.on('message', async(message) => {
    const { id: otherId, userType: otherUserType, messageType, content } = JSON.parse(message)

    if (messageType === 'system') { // 测试发送信息
      wsObj[wsKey].websocket.send(sendData('system', '')) // 原地返回
    } else {
      const query = {}
      // 拼接相应的数据
      switch (otherUserType) {
        case 'user':
          query['userId'] = otherId
          break
        case 'admin':
          query['adminId'] = otherId
          break
      }
      switch (userType) {
        case 'user':
          query['userId'] = id
          break
        case 'admin':
          query['adminId'] = id
          break
      }
      const group = await ChatGroup.findOne({ where: query })
      if (group) { // 已经创建了该聊天组
        // 消息存入数据库
        const res = await ChatList.create({
          ...query,
          messageType,
          content,
          groupId: group.groupId,
          userType
        })
        // 如果对方在线则发送消息
        if (res && wsObj[`${otherUserType}${otherId}`]) {
          const userInfo = await getUserInfo(query)
          wsObj[`${otherUserType}${otherId}`].websocket.send(sendData('chat', { user: userInfo[userType], userType, status: 'online', content }))
        }
        
      } else { // 没有则创建（只会在没有聊天组时触发，不会接受消息参数）
        const { user, admin } = await getUserInfo(query)
        await ChatGroup.create({ ...query, title: `${user.userName}与${admin.userName}的对话`})
      }
    }
  })
  ctx.websocket.on('close', (message) => {
    delete wsObj[id]
    console.log(`${id}用户掉线`, message)
    for (const prop in wsObj) {
      wsObj[prop].websocket.send(sendData('system', { id, userType, status: 'offline', content: `${prop}用户离线了`}))
    }
  })
}

// 转换JSON数据方法(type: system系统通知,chat聊天通知)
function sendData(type, data) {
  return JSON.stringify({ type, data })
}
// 获取用户信息
function getUserInfo({ userId, adminId }) {
  return new Promise(async(resolve) => {
    const admin_data = await User.findOne({ where: { id: adminId }})
    const user_data = await ShopUser.findOne({ where: { userId }})
    const admin_avatar = await getFile(admin_data.avatar)
    const user_avatar = await getFile(user_data.avatar)
    admin_data['avatar'] = admin_avatar
    user_data['avatar'] = user_avatar
    resolve({
      admin: {
        userName: admin_data.userName,
        avatar: admin_data.avatar[0].url
      },
      user: {
        userName: user_data.userName,
        avatar: user_data.avatar[0].url
      }
    })
  })
}
